﻿using System;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using System.Linq;
using Microsoft.SharePoint.Client;
using System.Collections.Generic;
using Microsoft.SharePoint;
using System.Linq.Expressions;

namespace ClientLibrary.VisualWebPart1
{
    [ToolboxItemAttribute(false)]
    public partial class VisualWebPart1 : WebPart
    {
        // Uncomment the following SecurityPermission attribute only when doing Performance Profiling using
        // the Instrumentation method, and then remove the SecurityPermission attribute when the code is ready
        // for production. Because the SecurityPermission attribute bypasses the security check for callers of
        // your constructor, it's not recommended for production purposes.
        // [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Assert, UnmanagedCode = true)]
        public VisualWebPart1()
        {
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            InitializeControl();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            
        }

        private void GetWebSiteProp()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            Web web = context.Web;
            context.Load(web);
            context.ExecuteQuery();

            lbl1.Text = web.Title;
        }

        private void GetCertainProp()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            Web web = context.Web;
            context.Load(web, w => w.Title, w => w.Description);
            context.ExecuteQuery();

            Label1.Text = web.Title;
            Label2.Text = web.Description;
        }

        private void UpdateWebProp()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            Web web = context.Web;

            web.Title = "SCOM";
            web.Description = "SCOM Description";

            web.Update();
            context.ExecuteQuery();

            Label1.Text = "Updated";
        }

        private void CreateWeb()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            WebCreationInformation webInfo = new WebCreationInformation();
            webInfo.Url = "web1";
            webInfo.Title = "Welcome web1";
            webInfo.Description = "description1";

            Web newweb = context.Web.Webs.Add(webInfo);

            context.Load(newweb, n => n.Title);
            context.ExecuteQuery();

            Label1.Text = newweb.Title;
        }

        private void RetrieveAllSPLists()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            Web web = context.Web;
            context.Load(web.Lists, lists => lists.Include(l => l.Title, l => l.Id));

            context.ExecuteQuery();
            
            foreach (List list in web.Lists)
            {
                Label1.Text = Label1.Text + "," + list.Title;
            }
        }

        private void RetrieveListByLoadQuery()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            Web web = context.Web;
            IEnumerable<List> result = context.LoadQuery(web.Lists.Include(l => l.Title, l => l.Id));
            context.ExecuteQuery();

            foreach (List list in web.Lists)
            {
                Label1.Text = Label1.Text + "," + list.Title;
            }
        }

        private void CreateList()
        {
            //spsecurity.runwithelevatedprivileges
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");
                Web web = context.Web;
                ListCreationInformation listInfo = new ListCreationInformation();
                listInfo.Title = "CSOM list";
                listInfo.Description = "SCOM Description";
                listInfo.TemplateType = (int)ListTemplateType.Announcements;

                List list = web.Lists.Add(listInfo);
                list.Update();
                context.ExecuteQuery();

                Label1.Text = "Created";
            });
        }

        private void DeleteList()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            Web web = context.Web;
            List list = web.Lists.GetByTitle("CSOM list");
            list.DeleteObject();
            context.ExecuteQuery();

            Label1.Text = "Deleted";
        }

        private void CreateField()
        {
            ClientContext context = new ClientContext("http://sp2013dev");
            List list = context.Web.Lists.GetByTitle("SCOM list");
            Field field = list.Fields.AddFieldAsXml("<Field DisplayName='MyField2' Type='Number' />",
                true, AddFieldOptions.DefaultValue);

            FieldNumber fldNumber = context.CastTo<FieldNumber>(field);
            fldNumber.MaximumValue = 100;
            fldNumber.MinimumValue = 40;
            fldNumber.Update();

            context.ExecuteQuery();

            Label1.Text = "Feidl Created";
        }

        private void CreateItem()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");
                List announcementsList = context.Web.Lists.GetByTitle("CSOM list");
                ListItemCreationInformation itemInfo = new ListItemCreationInformation();
                ListItem item = announcementsList.AddItem(itemInfo);
                item["Title"] = "CSOM Item";
                item["Body"] = "CSOM Body";

                item.Update();
                context.ExecuteQuery();
            });
        }

        private void RetrieveItems()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
            ClientContext context = new ClientContext("http://sp2013dev/");
                List announcementsList = context.Web.Lists.GetByTitle("CSOM list");
                CamlQuery query = CamlQuery.CreateAllItemsQuery();
                query.ViewXml = @"<QueryOptions>
                                    <ViewAttributes Scope='RecursiveAll' />
                                  </QueryOptions>";
                ListItemCollection col = announcementsList.GetItems(query);

                context.Load(col);
                context.ExecuteQuery();
                foreach (ListItem listItem in col)
                {
                    Label1.Text += listItem["Title"] +",";
                }
            });
        }

        private void UpdateItembyID()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");
                List announcementList = context.Web.Lists.GetByTitle("");
                ListItem listItem = announcementList.GetItemById(1);
                listItem["Title"] = "CSOM Updated";
                listItem.Update();
                context.ExecuteQuery();
            });
        }

        private void DeleteItembyID()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev/");
                List announcementList = context.Web.Lists.GetByTitle("");
                ListItem item = announcementList.GetItemById(1);
                item.DeleteObject();
                announcementList.Update();
                context.ExecuteQuery();
            });
        }

        private void GetFields()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev/");
                List announcementList = context.Web.Lists.GetByTitle("");
                context.Load(announcementList.Fields);
                context.ExecuteQuery();

                foreach (Field fld in announcementList.Fields)
                {
                    Label1.Text += fld.InternalName;
                }
            });
        }

        private void GetFieldProperty()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");
                List announcementList = context.Web.Lists.GetByTitle("");
                Field fld = announcementList.Fields.GetByInternalNameOrTitle("Title");
                FieldText fldTxt = context.CastTo<FieldText>(fld);
                context.Load(fldTxt);
                context.ExecuteQuery();

                Label1.Text = fldTxt.MaxLength.ToString();
            });
        }

        private void CreateGroup()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");

                //Permission Levels
                BasePermissions perm = new BasePermissions();
                perm.Set(PermissionKind.CreateAlerts);
                perm.Set(PermissionKind.ManageAlerts);

                //Permission level creation
                RoleDefinitionCreationInformation createInfo = new RoleDefinitionCreationInformation();
                createInfo.BasePermissions = perm;
                createInfo.Description = "A role that allows user to create alerts and manage alerts";
                createInfo.Name = "Alert Manager Role";
                createInfo.Order = 0;
                RoleDefinition role = context.Web.RoleDefinitions.Add(createInfo);

                //Create group
                GroupCreationInformation grpCreate = new GroupCreationInformation();
                grpCreate.Title = "CSOM grp";
                grpCreate.Description = "CSOM Description";
                Group grpcol = context.Web.SiteGroups.Add(grpCreate);

                //I want to give the permission level to the create group
                RoleDefinition rolDef = context.Web.RoleDefinitions.GetByName("Alert Manager Role");
                RoleDefinitionBindingCollection rdfcol = new RoleDefinitionBindingCollection(context);
                rdfcol.Add(rolDef);

                context.Web.RoleAssignments.Add(grpcol, rdfcol);
                
                context.ExecuteQuery();
            });
        }

        private void UsingExceptionHandlingScope()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");
                ExceptionHandlingScope scope = new ExceptionHandlingScope(context);
                
                using (scope.StartScope())
                {
                    using (scope.StartTry())
                    {
                        List list = context.Web.Lists.GetByTitle("CSOM list");
                        list.Description = "testing description";
                        list.Update();
                    }
                    using (scope.StartCatch())
                    {
                        ListCreationInformation listCreateInfo = new ListCreationInformation();
                        listCreateInfo.Title = "Sample";
                        listCreateInfo.Description = "Sample list description";
                        listCreateInfo.TemplateType = (int)ListTemplateType.Announcements;
                        List annList = context.Web.Lists.Add(listCreateInfo);
                    }
                    using (scope.StartFinally())
                    {
                        List list = context.Web.Lists.GetByTitle("Sample");
                        list.EnableFolderCreation = true;
                        list.Update();
                    }
                }
                context.ExecuteQuery();
            });
        }

        private void UsingConditionalScope()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ClientContext context = new ClientContext("http://sp2013dev");
                List list = context.Web.GetCatalog((int)ListTemplateType.WebPartCatalog);
                BasePermissions perm = new BasePermissions();
                perm.Set(PermissionKind.ManageLists);

                Expression<Func<bool>> testing = () =>
                    (list.ServerObjectIsNull == false) && (context.Web.DoesUserHavePermissions(perm).Value);

                    ConditionalScope scope = new ConditionalScope(context, testing);

                    using (scope.StartScope())
                    {
                        context.Load(list, l => l.Title);
                    }
                    context.ExecuteQuery();

                    Label1.Text = scope.TestResult.Value.ToString();

                    if (scope.TestResult.Value)
                    {
                        Label1.Text = list.Title;
                    }
            });
        }

        protected void btnGetWebProp_Click(object sender, EventArgs e)
        {
            GetWebSiteProp();
        }

        protected void btnGetCertainProp_Click(object sender, EventArgs e)
        {
            GetCertainProp();
        }

        protected void btnUpdateWebProp_Click(object sender, EventArgs e)
        {
            UpdateWebProp();
        }

        protected void btnCreateWeb_Click(object sender, EventArgs e)
        {

        }

        protected void btnRetrieveSPLists_Click(object sender, EventArgs e)
        {
            RetrieveAllSPLists();
        }

        protected void btnRetrieveByLoadQuery_Click(object sender, EventArgs e)
        {
            RetrieveListByLoadQuery();
        }

        protected void btnCreateList_Click(object sender, EventArgs e)
        {
            CreateList();
        }

        protected void btnDeleteList_Click(object sender, EventArgs e)
        {
            DeleteList();
        }

        protected void btnCreateField_Click(object sender, EventArgs e)
        {
            CreateField();
        }

        protected void btnCreateItem_Click(object sender, EventArgs e)
        {
            CreateItem();
        }

        protected void btnRetrieveItems_Click(object sender, EventArgs e)
        {
            RetrieveItems();
        }

        protected void btnUpdateItem_Click(object sender, EventArgs e)
        {
            UpdateItembyID();
        }

        protected void btnGetFields_Click(object sender, EventArgs e)
        {
            GetFields();
        }

        protected void btnCreateGroup_Click(object sender, EventArgs e)
        {
            CreateGroup();
        }

        protected void btnTestScope_Click(object sender, EventArgs e)
        {
            UsingExceptionHandlingScope();
        }

        protected void btnTestConditionScope_Click(object sender, EventArgs e)
        {
            UsingConditionalScope();
        }
    }
}
